/**
 * Created by cody on 2016/8/29.
 *
 * HTML5 单页面应用框架
 *
 * 1. page-container 管理所有的View
 *
 * 2. page-item 单个页面
 *
 */

(function(window,document,$){

    function copy(target,source){
        for(var p in source){
            if(source.hasOwnProperty(p)){
                target[p] = source[p];
            }
        }
    }

    var defaultRootClass = 'page-container';
    var defaultItemClass = 'page-item';
    var defaultAction = "menus";
    var options = {
        rootClass: defaultRootClass,
        itemClass: defaultItemClass,
        action: defaultAction,
        snippetPath:'/snippet/'
    };
    function SPA(data){
        this.options = options;
        if(data){
            copy(this.options,data);
        }
        this.$root = $('.'+this.options.rootClass);
        this.hashStack = [];
        this.params = {};
        this.beforeRemove = {};
        this.resumeCalllback = {};  //返回到摸个页面的回调
    }

    /**
     * url#name=cody&password=123456
     *
     * 获取key，对应的value
     * @param key
     * @returns {*}
     */
    SPA.prototype.getParam = function (key) {
        return this.params[key];
    }

    SPA.prototype.start = function(action){
        var thiz = this;
        window.onhashchange = function(event){
            console.log(event);
            thiz.parseAndLoad();
        }
        thiz.parseAndLoad();
    }

    SPA.prototype.addBeforeLeaveCallback = function(callback){
        var key = $('.'+this.options.itemClass).length - 1;
        this.beforeRemove[key] = callback;
    }

    SPA.prototype.addResumeCallback = function(resumeCallback){
        var key = $('.'+this.options.itemClass).length - 1;
        this.resumeCalllback[key] = resumeCallback;
    }

    SPA.prototype.setOptions = function(ops){
        copy(this.options,ops);
    }

    SPA.prototype.isGoBack = function (path) {
        var stack = this.hashStack;
        if(stack.length <= 1) return false;

        var last = stack[stack.length - 2];
        return path == last;
    }

    SPA.prototype.parseAndLoad = function () {
        var path = this.getHashPath();
        var data = this.parseHash(path);
        if(this.isGoBack(path)){
            this.hashStack.pop();
            var callback = this.resumeCalllback[this.hashStack.length - 1];
            if(callback){
                callback();
            }
            this.params = data || {action:'index'};
            this.removeLastPage();
        }else{
            console.log(data);
            this.hashStack.push(path);
            this.params = data;
            this.loadPage(data);
        }
    }

    SPA.prototype.getHashPath = function () {
        var hash = decodeURIComponent(location.hash);
        if(!hash){
            return '';
        }
        var index = hash.lastIndexOf('#');
        var path = hash.substring(index + 1);
        return path;
    }

    SPA.prototype.parseHash = function(path){

        if(!path){
            return undefined;
        }
        var kvs = path.split('&');
        var data = {};
        for(var i = 0;i < kvs.length;i ++){
            var kv = kvs[i].split('=');
            var key = kv[0];
            var value = kv.length > 1 ? kv[1] : '';
            data[key] = value;
        }

        return data;
    }

    SPA.prototype.loadPage=function (data){
        var url = undefined;
        if(!data || !data.action){
            url = this.options.index;
        }else{
            url = this.options[data.action];
            if(!url)
                url = this.options.snippetPath + data.action+'.html';
        }
        var $view = $('<div></div>').hide();
        $view.addClass(this.options.itemClass);
        $view.css('z-index',$('.'+this.options.itemClass).length + 1);
        this.$root.append($view);
        $view.fadeIn();
        console.log(url);
        $view.load(url,'_t=27',function(text,status,$xhr){

        });
    }

    SPA.prototype.removeLastPage = function () {
        var $last = this.$root.children('.'+ this.options.itemClass + ':last-child');
        var index = $last.index();
        if(this.beforeRemove && this.beforeRemove[index]){
            var callback = this.beforeRemove[index];
            if(callback){
                callback();
            }
        }
        $last.fadeOut(function(){
            $last.remove();
        });
    }

    window.SPA = SPA;
}(window,document,$));













